﻿using Commons.ASPNETCore;
using Commons.Infrastructure;
using IdentityService.Domain;
using Kogel.Repository;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IdentityService.Infrastructure
{
    public class UserManager : IUserManager
    {
        private readonly int MAX_FAILED = 5;
        private readonly IRepository<User> repository;
        private readonly IMemoryCacheHelper memoryCacheHelper;
        public UserManager(IRepository<User> repository , IMemoryCacheHelper memoryCacheHelper)
        {
          this.repository = repository;
           this.memoryCacheHelper = memoryCacheHelper;
        }

        public (bool, int) AccessFailed(User user)
        {
            if (user == null)
            {
                return (false, -1);
            }

            int errCount = memoryCacheHelper.GetOrCreate($"UserManager.AccessFailed.{user.Id}",
                  (e) => 0);
            memoryCacheHelper.Set($"UserManager.AccessFailed.{user.Id}", errCount++);
            return (false, errCount);
        }

        public Task<bool> AccessFailedAsync(User user)
        {
            throw new NotImplementedException();
        }

        public bool CheckPassword(User user, string password)
        {
            if (user == null)
            {
                return false;
            }
            //  return user.Md5Password == password;
            return user.Password == password;
        }

        public Task<bool> CheckPasswordAsync(User user, string password)
        {
            throw new NotImplementedException();
        }

        public async Task<bool> CreateAsync(User user)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            var result = await repository.InsertAsync(user);
            return result ==1;
        }

        public async Task<User?> FindByIdAsync(long userId)
        {
            return await repository.QueryFirstAsync(x=>x.Id==userId);
        }

        public async Task<User?> FindByNameAsync(string userName)
        {
            return await repository.QuerySet().Where(u => u.UserName == userName).GetAsync();
        }

        public Task<User?> FindByPhoneNumberAsync(string phoneNum)
        {
            throw new NotImplementedException();
        }

        public (bool, int) IsLockedOut(User user)
        {
            int count = memoryCacheHelper.GetOrCreate($"UserManager.AccessFailed.{user.Id}",
                  (e) => 0);
            return (count >= MAX_FAILED, count);
        }
    }
}
